home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Graphics_Utils / aMiPEG_1.1 / src / readfile.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  19KB  |  754 lines

  1. /* readfile.c */
  2.  
  3. #include "video.h"
  4. #include "proto.h"
  5.  
  6. #include <proto/asyncio.h>
  7.  
  8. /* Stream IDs */
  9. int gAudioStreamID=0;
  10. int gVideoStreamID=0;
  11. int gReservedStreamID=0;
  12.  
  13. #ifdef ANALYSIS
  14. int gNumAudioPackets=0;
  15. int gNumVideoPackets=0;
  16. int gNumPaddingPackets=0;
  17. int gNumReservedPackets=0;
  18. int gNumPrivate_1_Packets=0;
  19. int gNumPrivate_2_Packets=0;
  20. #endif
  21.  
  22. extern int sys_layer=-1;
  23. extern int EOF_flag;
  24. extern int quietFlag;
  25.  
  26. // static FILE *hack;
  27. FILE *out;
  28.  
  29. /*
  30.  *--------------------------------------------------------------
  31.  *
  32.  * get_more_data --
  33.  *
  34.  *    Called by correct_underflow in bit parsing utilities to
  35.  *      read in more data. Checks if System Layer etc.
  36.  *
  37.  * Results:
  38.  *    Input buffer updated, buffer length updated.
  39.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  40.  *
  41.  * Side effects:
  42.  *      None.
  43.  *
  44.  *--------------------------------------------------------------
  45.  */
  46. int get_more_data(bs_ptr, max_length, length_ptr, buf_ptr)
  47. unsigned int **bs_ptr;
  48. int *max_length, *length_ptr;
  49. unsigned int **buf_ptr;
  50. {
  51.   int ioBytes, data, result;
  52.  
  53.   if (sys_layer == 0) {
  54.     return pure_get_more_data(*bs_ptr, *max_length, length_ptr, buf_ptr);
  55.   }
  56.   if (sys_layer == -1) {
  57. //    hack=fopen("hack.dat", "w");
  58.     /* Time to init ourselves */
  59.     ioBytes = ReadAsync(input, &data, 4);
  60.     if (ioBytes!=4) return 0;
  61.     if ((data==PACK_START_CODE) || (data==SYSTEM_HEADER_START_CODE)) {
  62.       /* Yow, a System Layer Stream.  Much harder to parse.  Call in the
  63.      specialist.... */
  64.       if(!quietFlag) {
  65.         fprintf(stderr,"This is an MPEG System Layer Stream.  ");
  66.         fprintf(stderr,"Audio is not processed.\n");
  67.       }
  68.       sys_layer=1;
  69.       result= read_sys(bs_ptr, max_length, length_ptr, buf_ptr, data);
  70. // fwrite((unsigned char *)(*buf_ptr),1,*length_ptr*4,hack);
  71.       return result;
  72.     } else {
  73.       /* No system Layer junk, just pretend we didn't peek,
  74.      and hereafter just call pure_get_more_data */
  75.       sys_layer=0;
  76.       **bs_ptr=data;
  77.       *length_ptr=1;
  78.       result= pure_get_more_data(*bs_ptr, *max_length, 
  79.                  length_ptr, buf_ptr);
  80.       *buf_ptr= *bs_ptr;
  81.       return result;
  82.     }
  83.   }
  84.   /* A system layer stream (called after the 1st time), call the specialist */
  85. // data= *length_ptr;
  86.   result=read_sys(bs_ptr, max_length, length_ptr, buf_ptr, 0);
  87.  
  88. // fwrite((unsigned char *) ((*buf_ptr)+data),1,4*((*length_ptr)-data),hack);
  89.  
  90.   return result;
  91. }
  92.  
  93. /*
  94.  *--------------------------------------------------------------
  95.  *
  96.  * pure_get_more_data --
  97.  *
  98.  *    Called by get_more_data to
  99.  *      read in more data in normal case streams.
  100.  *
  101.  * Results:
  102.  *    Input buffer updated, buffer length updated.
  103.  *      Returns 1 if data read, 0 if EOF, -1 if error.
  104.  *
  105.  * Side effects:
  106.  *      None.
  107.  *
  108.  *--------------------------------------------------------------
  109.  */
  110.  
  111. int pure_get_more_data(unsigned int *buf_start, int max_length, int *length_ptr, unsigned int **buf_ptr)
  112. {
  113.   
  114.   int length, num_read, request;
  115.   unsigned char *buffer, *mark;
  116.  
  117.   if (EOF_flag) return 0;
  118.  
  119.   length = *length_ptr;
  120.   buffer = (unsigned char *) *buf_ptr;
  121.  
  122.   if (length > 0) {
  123.     memcpy((unsigned char *) buf_start, buffer, (length*4));
  124.     mark = ((unsigned char *) (buf_start + length));
  125.   }
  126.   else {
  127.     mark = (unsigned char *) buf_start;
  128.     length = 0;
  129.   }
  130.  
  131.   request = (max_length-length)*4;
  132.   
  133.     num_read = ReadAsync(input, mark, request);
  134.  
  135.   /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
  136.   {
  137.     int num_read_rounded;
  138.     unsigned char *index;
  139.  
  140.     num_read_rounded = num_read & 0xfffffffc;
  141.  
  142.     /* this can happen only if num_read<request; i.e. end of file reached */
  143.     if( num_read_rounded < num_read )
  144.       { 
  145.      num_read_rounded+=4;
  146.      /* fill in with zeros */
  147.      for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
  148.      /* advance to the next 4-byte boundary */
  149.      num_read = num_read_rounded;
  150.       }
  151.   }
  152.   
  153.   if (num_read < 0) {
  154.     return -1;
  155.   }
  156.   else if (num_read == 0) {
  157.     *buf_ptr = buf_start;
  158.     
  159.     /* Make 32 bits after end equal to 0 and 32
  160.        bits after that equal to seq end code
  161.        in order to prevent messy data from infinite
  162.        recursion.
  163.     */
  164.  
  165.     *(buf_start + length) = 0x0;
  166.     *(buf_start + length+1) = SEQ_END_CODE;
  167.  
  168.     EOF_flag = 1;
  169.     return 0;
  170.   }
  171.  
  172.   num_read >>= 2;
  173.  
  174.   *buf_ptr = buf_start;
  175.   *length_ptr = length + num_read;
  176.  
  177.   return 1;
  178. }
  179. /*
  180.  *----------------------------------------------------------
  181.  *
  182.  *  read_sys
  183.  *
  184.  *      Parse out a packet of the system layer MPEG file.
  185.  *
  186.  *  Results:  Returns 0 if error or EOF
  187.  *            Returns 1 if more data read (could be just one int)
  188.  *
  189.  *  Side Effects:  ReadPacket can change *bs_ptr to be a new buffer
  190.  *                 buf_ptr will remain pointing at *length_ptr (at input)
  191.  *                         into the buffer
  192.  *                 *length_ptr will be changed to the new size
  193.  *                 *max_length can be changed if a new buffer is alloc'd
  194.  *
  195.  *----------------------------------------------------------
  196.  */
  197. int read_sys(bs_ptr, max_length, length_ptr, buf_ptr, start)
  198.      unsigned int **bs_ptr;
  199.      int *max_length, *length_ptr;
  200.      unsigned int **buf_ptr, start;  
  201.      /* start is either a start code or 0 to indicate continued parsing */
  202. {
  203.   unsigned int startCode;
  204.   int errorCode, PacketReply;
  205.   unsigned char packetID;
  206.   double systemClockTime;
  207.   unsigned long muxRate;
  208.   /* Statistics */
  209.   static int numPacks = 0;
  210.   static int numPackets = 0;
  211.   static int numSystemHeaders = 0;
  212.   static BOOLEAN Parse_done=FALSE;
  213.   BOOLEAN match;
  214.   
  215.   if (!start) {
  216.     errorCode = ReadStartCode(&startCode);
  217.     if (EOF_flag) return 0;
  218.     if (errorCode != 0) {
  219.       fprintf(stderr, "Unable to read initial pack start code\n");
  220.       return 0;
  221.     }
  222.   }
  223.   else {
  224.     errorCode = 0;
  225.     startCode = start;
  226.   }
  227.   
  228.   while (1) {
  229.     match=FALSE;
  230.     if (startCode == PACK_START_CODE) {
  231.       ++numPacks; match=TRUE;
  232.       errorCode = ReadPackHeader( &systemClockTime, &muxRate);
  233.       if (errorCode != 0) {
  234.         fprintf(stderr, "Error in reading pack header\n");
  235.         return 0;
  236.       }
  237.       errorCode = ReadStartCode( &startCode);
  238.       if (errorCode != 0) {
  239.         fprintf(stderr, "Error in reading start code\n");
  240.         return 0;
  241.       }
  242.     }
  243.     if (startCode == SYSTEM_HEADER_START_CODE) {
  244.       ++numSystemHeaders; match=TRUE;
  245.       errorCode = ReadSystemHeader();
  246.       if (errorCode != 0) {
  247.     fprintf(stderr, "Error in reading system header\n");
  248.     return 0;
  249.       }
  250.       errorCode = ReadStartCode( &startCode);
  251.       if (errorCode != 0) {
  252.     fprintf(stderr,"Error in reading start code after system header\n");
  253.     return 0;
  254.       }
  255.     }
  256.     packetID = startCode & 0xff;
  257.     while (((startCode & PACKET_START_CODE_MASK) == PACKET_START_CODE_PREFIX) &&
  258.        (packetID>=0xbc)) {
  259.       ++numPackets; match=TRUE;
  260.       packetID = startCode & 0xff;
  261.       PacketReply = ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr);
  262.       switch (PacketReply) {
  263.       case 2: 
  264.         return 1;
  265.       case 1: 
  266.         return 0;
  267.       default: /* do nothing */
  268.         break;
  269.       }
  270.       errorCode = ReadStartCode( &startCode);
  271.       if (errorCode != 0) {
  272.         fprintf(stderr,"Error in start code after packet\n");
  273.         /*printf("startCode: %08lx\n", startCode);*/
  274.         return 0;
  275.       }
  276.       if (startCode == PACK_START_CODE || startCode == ISO_11172_END_CODE)
  277.         break;
  278.     }
  279.     if (startCode == ISO_11172_END_CODE) {
  280.       if (Parse_done) return 1;
  281. #ifdef ANALYSIS
  282.       fprintf(stderr, "Successful parse of MPEG system level\n");
  283.       fprintf(stderr, "%d system headers, %d packs, %d packets\n",
  284.           numSystemHeaders, numPacks, numPackets);
  285.       fprintf(stderr, "%d audio packets, %d video packets, %d padding packets\n",
  286.           gNumAudioPackets, gNumVideoPackets, gNumPaddingPackets);
  287.       fprintf(stderr, "%d reserved packets, %d/%d private type 1/2 packets\n",
  288.           gNumReservedPackets, gNumPrivate_1_Packets, gNumPrivate_2_Packets);
  289. #endif
  290.       ReadPacket(NOT_PACKET_ID, bs_ptr, max_length, length_ptr, buf_ptr);
  291.       Parse_done=TRUE;
  292.       return 1;
  293.     }
  294.     if (errorCode != 0)
  295.       return 1;
  296.     if (!match) {
  297.       fprintf(stderr,"\nNo match found for start code %08x in system layer, skipping\n",startCode);
  298.       startCode=(int) find_start_code();
  299.       if (startCode==EOF) {
  300.         EOF_flag=1;
  301.         return 0;
  302.       }
  303.     }
  304.   }
  305.   return 0; /* shouldnt get here */
  306. }
  307.  
  308. /*
  309.  *-----------------------------------------------------------
  310.  *
  311.  *  ReadStartCode
  312.  *
  313.  *      Parses a start code out of the stream
  314.  *
  315.  *  Results/Side Effects:  Sets *startCode to the code, returns
  316.  *     1 on error, 0 on success
  317.  *
  318.  *-----------------------------------------------------------
  319.  */
  320. int ReadStartCode(startCode)
  321.      unsigned int *startCode;
  322. {
  323.   int numRead;
  324.   
  325.   numRead = ReadAsync(input, (unsigned char *)startCode, 4);
  326.   
  327.   if (numRead < 4) {
  328.     EOF_flag=1;
  329.     return 1;
  330.   }
  331.   if ((*startCode&0xfffffe00) != 0) {
  332.     fprintf(stderr,"Problem with system layer parse, skipping to start code\n");
  333.     *startCode=(int) find_start_code();
  334.     if (*startCode==EOF) {
  335.       EOF_flag=TRUE;
  336.       return 0;
  337.     }
  338.   }
  339.   return 0;
  340. }
  341.  
  342.  
  343.  
  344. /*
  345.  *-----------------------------------------------------------
  346.  *
  347.  *  find_start_code
  348.  *
  349.  *      Parses a start code out of the stream by tossing bytes until it gets one
  350.  *
  351.  *  Results/Side Effects:  Parses bytes of the stream, returns code
  352.  *                         Returns EOF in case of end of file
  353.  *
  354.  *-----------------------------------------------------------
  355.  */
  356. int find_start_code(void)
  357. {
  358.  NO_ZEROS:
  359.   switch(ReadCharAsync(input)) {
  360.   case 0:    goto ONE_ZERO;
  361.   case EOF:  goto EOF_FOUND;
  362.   default:   goto NO_ZEROS;
  363.   }
  364.  
  365.  ONE_ZERO:
  366.   switch(ReadCharAsync(input)) {
  367.   case 0:    goto TWO_ZEROS;
  368.   case EOF:  goto EOF_FOUND;
  369.   default:   goto NO_ZEROS;
  370.   }
  371.  
  372.  TWO_ZEROS:
  373.   switch(ReadCharAsync(input)) {
  374.   case 0x01:  goto CODE_FOUND;
  375.   case 0x00:  goto TWO_ZEROS;
  376.   case EOF:  goto EOF_FOUND;
  377.   default:    goto NO_ZEROS;
  378.   }
  379.  
  380.  CODE_FOUND:
  381.   return 0x00000100+ReadCharAsync(input);
  382.  
  383.  EOF_FOUND:   /* received EOF */
  384.   return EOF;
  385. }
  386.  
  387. /*
  388.  *-----------------------------------------------------------------
  389.  *
  390.  *  ReadPackHeader
  391.  *
  392.  *      Parses out the PACK header
  393.  *
  394.  *  Returns: 1 on error, 0 on success
  395.  *
  396.  *-------------------------------------------------------------------
  397.  */
  398. int ReadPackHeader(systemClockTime,muxRate)
  399.      double *systemClockTime;
  400.      unsigned long *muxRate;
  401. {
  402.   int numRead;
  403.   unsigned char inputBuffer[PACK_HEADER_SIZE];
  404.   unsigned long systemClockRef;
  405.   unsigned char systemClockRefHiBit;
  406.   
  407.   numRead = ReadAsync(input, inputBuffer, PACK_HEADER_SIZE);  
  408.  
  409.   if (numRead < PACK_HEADER_SIZE) {
  410.     EOF_flag=1;
  411.     return 1;
  412.   }
  413.   ReadTimeStamp(inputBuffer, &systemClockRefHiBit, &systemClockRef);
  414.   MakeFloatClockTime(systemClockRefHiBit, systemClockRef, systemClockTime);
  415.   ReadRate(&inputBuffer[5], muxRate);
  416.   *muxRate *= MUX_RATE_SCALE_FACTOR;
  417.   return 0;
  418. }
  419.  
  420. /*
  421.  *------------------------------------------------------------------
  422.  *
  423.  *   ReadSystemHeader
  424.  *
  425.  *      Parse out the system header, setup out dtream IDs for parsing packets
  426.  *
  427.  *   Results:  Returns 1 on error, 0 on success.
  428.  *             Sets gAudioStreamID and gVideoStreamID
  429.  *
  430.  *------------------------------------------------------------------
  431.  */
  432. int ReadSystemHeader()
  433.   unsigned char *inputBuffer;
  434.   int numRead;
  435.   int pos;
  436.   unsigned short headerSize;
  437.   unsigned char streamID;
  438.   /* Only needed for system log file */
  439.   
  440.   numRead = ReadAsync(input, (char *)&headerSize, 2);
  441.  
  442.   if (numRead != 2) {
  443.     EOF_flag=1;
  444.     return 1;
  445.   }
  446.   inputBuffer = (unsigned char *) malloc(headerSize+1);
  447.   if (inputBuffer == NULL) {
  448.     return 1;
  449.   }
  450.   inputBuffer[headerSize]=0;
  451.   numRead = ReadAsync(input, inputBuffer, headerSize);
  452.   if (numRead < headerSize) {
  453.     EOF_flag=1;
  454.     return 1;
  455.   }
  456.   
  457.   pos = 6;
  458.   while ((inputBuffer[pos] & 0x80) == 0x80) {
  459.     streamID = inputBuffer[pos];
  460.     switch (streamID) {
  461.     case STD_VIDEO_STREAM_ID: 
  462.       break;
  463.     case STD_AUDIO_STREAM_ID: 
  464.       break;
  465.     case RESERVED_STREAM_ID: 
  466.       break;
  467.     case PADDING_STREAM_ID: 
  468.       break;
  469.     case PRIVATE_STREAM_1_ID: 
  470.       break;
  471.     case PRIVATE_STREAM_2_ID: 
  472.       break;
  473.     case 0xb1:
  474.       if (streamID < MIN_STREAM_ID_ID) {
  475.     return 1;
  476.       }
  477.       
  478.     default:
  479.       if (streamID < MIN_STREAM_ID_ID) {
  480.     return 1;
  481.       }
  482.       switch (streamID >> 4) {
  483.       case 0xc:
  484.       case 0xd:
  485.     gAudioStreamID = streamID;
  486.     break;
  487.       case 0xe:
  488.     if ((gVideoStreamID != 0) && (gVideoStreamID!=streamID)) {
  489.       break;
  490.     }
  491.     gVideoStreamID = streamID;
  492.     break;
  493.       case 0xf:
  494.     gReservedStreamID = streamID;
  495.     break;
  496.       }
  497.       break;
  498.     }
  499.     pos += 3;
  500.   }
  501.   if (inputBuffer)
  502.     free(inputBuffer);
  503.   return 0;
  504. }
  505.  
  506. /*
  507.  *-----------------------------------------------------------------
  508.  *
  509.  *  ReadPacket
  510.  *
  511.  *      Reads a single packet out of the stream, and puts it in the
  512.  *      buffer if it is video.
  513.  *
  514.  *  Results:
  515.  *      Changes the value of *length_ptr to be the new length (plus old)
  516.  *      If the buffer is too small, can change *bs_ptr, *max_length, and *buf_ptr
  517.  *      to be correct for a newly allocated buffer.
  518.  *
  519.  *  State:  The buffer is in ints, but the packets can be an arbitrary number
  520.  *      of bytes, so leftover bytes are kept in static vars and added in on the
  521.  *      next call.
  522.  *
  523.  *-----------------------------------------------------------------
  524.  */   
  525. int ReadPacket(packetID, bs_ptr, max_length, length_ptr, buf_ptr) 
  526. unsigned char packetID;
  527. unsigned int **bs_ptr;
  528. int *max_length;
  529. int *length_ptr;
  530. unsigned int **buf_ptr;
  531. /* Returns:
  532.    0 - no error, but not video packet we want
  533.    1 - error
  534.    2 - got video packet into buffer
  535.    */
  536. {   
  537.   int ioBytes;
  538.   unsigned char nextByte;
  539.   unsigned short packetLength;
  540.   unsigned char *packetBuffer;
  541.   int pos;
  542.   int packetDataLength;
  543.   int byte_length;
  544.   /* Leftovers from previous video packets */
  545.   static unsigned int num_left=0, leftover_bytes=0;
  546.   
  547.   if (packetID==NOT_PACKET_ID) {
  548.     /* Gross hack to handle unread bytes before end of stream */
  549.     if (num_left!=0) {
  550.       /* Sigh, deal with previous leftovers */
  551.       *(*buf_ptr+*length_ptr)=leftover_bytes;
  552.       *(*buf_ptr+*length_ptr+1)=ISO_11172_END_CODE;
  553.       *length_ptr+=2;
  554.     } else {
  555.       *(*buf_ptr+*length_ptr)=ISO_11172_END_CODE;
  556.       *length_ptr+=1;
  557.     }
  558.     return 1;
  559.   }
  560.   
  561.   ioBytes = ReadAsync(input, &packetLength, 2);
  562.   if (ioBytes < 2) {
  563.     return 1;
  564.   }
  565.   if (packetID == gAudioStreamID) {
  566. #ifdef ANALYSIS
  567.     ++gNumAudioPackets;
  568. #endif
  569.   }
  570.   else if (packetID == gVideoStreamID) {
  571. #ifdef ANALYSIS     
  572.     ++gNumVideoPackets;
  573. #endif
  574.   }
  575.   else {
  576.     switch (packetID) {
  577.     case PADDING_STREAM_ID:
  578. #ifdef ANALYSIS
  579.       ++gNumPaddingPackets;
  580. #endif
  581.       break;
  582.     case RESERVED_STREAM_ID:
  583. #ifdef ANALYSIS
  584.       ++gNumReservedPackets;
  585. #endif
  586.       break;
  587.     case PRIVATE_STREAM_1_ID:
  588. #ifdef ANALYSIS
  589.       ++gNumPrivate_1_Packets;
  590. #endif
  591.       break;
  592.     case PRIVATE_STREAM_2_ID:
  593. #ifdef ANALYSIS
  594.       ++gNumPrivate_2_Packets;
  595. #endif
  596.       break;
  597.     default:
  598.       if (packetID < MIN_STREAM_ID_ID){
  599.           return 1;
  600.       }
  601.       switch(packetID >> 4){
  602.       case 0xc:
  603.       case 0xd:
  604.           packetID = gAudioStreamID;
  605.       break;
  606.       case 0xe:
  607.           if ((gVideoStreamID != 0)&&(gVideoStreamID != packetID)){
  608.           break;
  609.           }
  610.           gVideoStreamID = packetID;
  611.       break;
  612.       }
  613.       break;
  614.       
  615. /*      fprintf(stderr, "\nUnknown packet type encountered. P'bly audio? (%x) at %d\n", <---- obsolete
  616.           packetID,(int) SeekAsync(input, 0, MODE_CURRENT));                        <----    "     */
  617.     } /* switch */
  618.   } /* else */
  619.  
  620.  
  621.   if (packetID != gVideoStreamID) {
  622.     SeekAsync(input, packetLength, MODE_CURRENT);
  623.     return 0;
  624.   }
  625.  
  626.  
  627.   nextByte=ReadCharAsync(input);
  628.  
  629.   pos = 0;
  630.   while (nextByte & 0x80) {
  631.     ++pos;
  632.     nextByte=ReadCharAsync(input);
  633.   }
  634.   if ((nextByte >> 6) == 0x01) {
  635.     pos += 2;
  636.     ReadCharAsync(input);
  637.     nextByte=ReadCharAsync(input);
  638.   } 
  639.   if ((nextByte >> 4) == 0x02) {
  640.     SeekAsync(input, 4, MODE_CURRENT);
  641.     nextByte=ReadCharAsync(input);
  642.     pos+=5;
  643.   }
  644.   else if ((nextByte >> 4) == 0x03) {
  645.     SeekAsync(input, 9, MODE_CURRENT);
  646.     nextByte=ReadCharAsync(input);
  647.     pos += 10;
  648.   } 
  649.   else {
  650.     nextByte=ReadCharAsync(input);
  651.     pos += 1;
  652.   }
  653.  
  654.   /* Read all the headers, now make room for packet */
  655.   if (*bs_ptr+*max_length<*buf_ptr+packetLength/4+*length_ptr) {
  656.     if (*max_length-*length_ptr<packetLength/4) {
  657.       /* Buffer too small for a packet (plus whats there),
  658.          time to enlarge it! */
  659.       unsigned int *old= *bs_ptr;
  660.       *max_length = *length_ptr + packetLength/2;
  661.       *bs_ptr=(unsigned int *)malloc(*max_length*4);
  662.       if (*bs_ptr == NULL) {
  663.         return 1;
  664.       }
  665.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  666.       free(old);
  667.       *buf_ptr= *bs_ptr;
  668.     } else {
  669.       memcpy((unsigned char *)*bs_ptr,*buf_ptr,*length_ptr*4);
  670.       *buf_ptr = *bs_ptr;
  671.     }
  672.   }
  673.  
  674.   byte_length= (*length_ptr)*4;
  675.   if (num_left!=0) {
  676.     /* Sigh, deal with previous leftovers */
  677.     byte_length += num_left;
  678.     *(*buf_ptr+*length_ptr)=leftover_bytes;
  679.   }
  680.   packetBuffer=((unsigned char *)*buf_ptr)+byte_length;
  681.   packetDataLength = packetLength - pos;
  682.   *packetBuffer++=nextByte;
  683.   if (packetID == gVideoStreamID) {
  684.     ioBytes=ReadAsync(input, packetBuffer, packetDataLength-1); 
  685.     if (ioBytes!=packetDataLength-1) {
  686.       EOF_flag=1;
  687.       return 1;
  688.     }
  689.  
  690.     byte_length = byte_length+packetDataLength;
  691.     num_left = byte_length%4;
  692.     *length_ptr = byte_length/4;
  693.     leftover_bytes = *(*buf_ptr+*length_ptr);
  694.     return 2;
  695.   }
  696.   else if (packetID == gAudioStreamID) { 
  697.     packetBuffer = (unsigned char *)(*buf_ptr+*length_ptr+1);
  698.     ReadAsync(input, packetBuffer, packetDataLength-1);
  699.  
  700. /*        if(!out)
  701.             out = fopen("ram:out", "w");
  702.  
  703.         fwrite(packetBuffer, 1, packetDataLength-1, out);*/
  704.  
  705.   }
  706.   else /* Donno what it is, just nuke it */ {
  707.     /* This code should be unreachable */
  708.     packetBuffer=(unsigned char *)(*buf_ptr+*length_ptr+1);
  709.     ReadAsync(input, packetBuffer, packetDataLength-1);
  710.   }
  711.   return 0; 
  712. }
  713.  
  714. /*
  715.  * A formatting utility procedure.
  716.  */
  717. void ReadTimeStamp(inputBuffer,hiBit,low4Bytes)
  718.      unsigned char *inputBuffer, *hiBit;
  719.      unsigned long *low4Bytes;
  720. {
  721.   *hiBit = ((unsigned long)inputBuffer[0] >> 3) & 0x01;
  722.   *low4Bytes = (((unsigned long)inputBuffer[0] >> 1) & 0x03) << 30; 
  723.   *low4Bytes |= (unsigned long)inputBuffer[1] << 22; 
  724.   *low4Bytes |= ((unsigned long)inputBuffer[2] >> 1) << 15; 
  725.   *low4Bytes |= (unsigned long)inputBuffer[3] << 7; 
  726.   *low4Bytes |= ((unsigned long)inputBuffer[4]) >> 1; 
  727. }
  728. void ReadRate(inputBuffer,rate)
  729.      unsigned char *inputBuffer;
  730.      unsigned long *rate;
  731. {
  732.   *rate = (inputBuffer[0] & 0x7f) << 15;
  733.   *rate |= inputBuffer[1] << 7;
  734.   *rate |= (inputBuffer[2] & 0xfe) >> 1;
  735. }
  736.  
  737. #define FLOAT_0x10000 (double)((unsigned long)1 << 16)
  738.  
  739. int MakeFloatClockTime(hiBit,low4Bytes,floatClockTime)
  740.      unsigned char hiBit;
  741.      unsigned long low4Bytes;
  742.      double *floatClockTime;
  743. {
  744.   if (hiBit != 0 && hiBit != 1) {
  745.     *floatClockTime = 0.0;
  746.     return 1;
  747.   }
  748.   *floatClockTime 
  749.     = (double)hiBit*FLOAT_0x10000*FLOAT_0x10000 + (double)low4Bytes;
  750.   *floatClockTime /= (double)90000;
  751.   return 0;
  752. }
  753.